package me.firstapp.service.weixin.transfer.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import me.firstapp.common.exception.ServiceException;
import me.firstapp.common.exception.StatusHouse;
import me.firstapp.common.utils.DateUtils;
import me.firstapp.common.utils.MD5Utils;
import me.firstapp.common.utils.Page;
import me.firstapp.common.utils.StrUtils;
import me.firstapp.module.weixin.jinbi.JinBiAccount;
import me.firstapp.module.weixin.jinbi.JinBiAccountTrace;
import me.firstapp.module.weixin.member.Member;
import me.firstapp.module.weixin.system.ThisSystem;
import me.firstapp.module.weixin.transfer.TransferMemberProduct;
import me.firstapp.module.weixin.transfer.TransferMemberProductItem;
import me.firstapp.module.weixin.transfer.TransferMemberRecord;
import me.firstapp.repository.weixin.jinbi.JinBiAccountRepository;
import me.firstapp.repository.weixin.jinbi.JinBiAccountTraceRepository;
import me.firstapp.repository.weixin.member.MemberRepository;
import me.firstapp.repository.weixin.system.ThisSystemRepository;
import me.firstapp.repository.weixin.transfer.TransferMemberProductItemRepository;
import me.firstapp.repository.weixin.transfer.TransferMemberProductRepository;
import me.firstapp.repository.weixin.transfer.TransferMemberRecordRepository;
import me.firstapp.service.weixin.transfer.TransferMemberRecordService;

@Service
public class TransferMemberRecordServiceImpl implements TransferMemberRecordService {

	private static Logger logger = LoggerFactory.getLogger(TransferMemberRecordServiceImpl.class);

	@Autowired
	private MemberRepository memberRepository;

	@Autowired
	private TransferMemberProductRepository transferMemberProductRepository;

	@Autowired
	private TransferMemberProductItemRepository transferMemberProductItemRepository;

	@Autowired
	private ThisSystemRepository thisSystemRepository;

	@Autowired
	private TransferMemberRecordRepository transferMemberRecordRepository;

	@Autowired
	private JinBiAccountRepository jinBiAccountRepository;

	@Autowired
	private JinBiAccountTraceRepository jinBiAccountTraceRepository;

	@Override
	public TransferMemberRecord executeAddTransferMemberRecord(String openId, Long transferMemberProductId) {
		Member member = memberRepository.findMemberByOpenId(openId);
		if (null == member) {
			throw new ServiceException(StatusHouse.STATUS_MEMBER_NOT_EXIST);
		}
		if (Member.STATUS_NO_USE == member.getStatus()) {
			throw new ServiceException(StatusHouse.STATUS_MEMBER_NO_USE_ERROR);
		}
		if (Member.FOLLOW_STATUS_NO == member.getFollowStatus()) {
			throw new ServiceException(StatusHouse.STATUS_PAGE_ERROR_NOT_CONCERN_WEIXIN);
		}
		if (Member.VIP_LEVEL_HIGHT != member.getVipLevel()) {
			throw new ServiceException("error", "只有代理才可以接收");
		}
		TransferMemberProduct transferMemberProduct = (TransferMemberProduct) transferMemberProductRepository
				.getById(transferMemberProductId);
		if (null == transferMemberProduct) {
			throw new ServiceException("error", "转让不存在");
		}
		if (TransferMemberProduct.STATUS_OFF == transferMemberProduct.getStatus()
				|| TransferMemberProduct.STATUS_SELLED == transferMemberProduct.getStatus()) {
			throw new ServiceException("error", "转让不存在");
		}
		if (transferMemberProduct.getOwnOpenId().equals(openId)) {
			throw new ServiceException("error", "自己不能接收自己的转让用户");
		}
		transferMemberProduct.setStatus(TransferMemberProduct.STATUS_SELLED);
		transferMemberProduct.setSaleTime(new Date());
		transferMemberProductRepository.update(transferMemberProduct);

		List<TransferMemberProductItem> transferMemberProductItems = transferMemberProductItemRepository
				.findByTransferMemberProductId(transferMemberProductId);
		if (null == transferMemberProductItems || transferMemberProductItems.isEmpty()) {
			throw new ServiceException("error", "转让不存在");
		}

		Member chiefMember = memberRepository.findMemberByOpenId(member.getChiefOpenId());
		for (TransferMemberProductItem transferMemberProductItem : transferMemberProductItems) {
			Long memberId = transferMemberProductItem.getMemberId();
			if (memberId.equals(chiefMember.getId()) || memberId.equals(member.getId())) {
				throw new ServiceException("error", "被转让的用户包含你的上级，不可接收");
			}
		}

		member.setFlow(member.getFlow() + 1);
		memberRepository.update(member);

		String orderNoStart = DateUtils.getNowStr("yyMMdd") + member.getId();
		String orderNoEnd = String.valueOf(member.getFlow());
		ThisSystem thisSystem = thisSystemRepository.findThisSystem();
		int lenth = thisSystem.getOrderNoLength() - orderNoStart.length() - orderNoEnd.length();
		StringBuffer sb = new StringBuffer("");
		for (int i = 0; i < lenth; i++) {
			sb.append(String.valueOf(StrUtils.getRandomInt()));
		}

		TransferMemberRecord transferMemberRecord = new TransferMemberRecord();
		transferMemberRecord
				.setRecordNo(TransferMemberRecord.RECORD_NO_START + orderNoStart + sb.toString() + orderNoEnd);
		transferMemberRecord.setOpenId(openId);
		transferMemberRecord.setCardNo(member.getCardNo());
		transferMemberRecord.setTransferMemberProductId(transferMemberProductId);
		transferMemberRecord.setCounts(transferMemberProduct.getCounts());
		transferMemberRecord.setPayAmount(transferMemberProduct.getAmount());
		transferMemberRecord.setStatus(TransferMemberRecord.STATUS_NOT_PAY);
		transferMemberRecord.setCreateTime(new Date());
		transferMemberRecordRepository.save(transferMemberRecord);

		return transferMemberRecord;
	}

	@Override
	public TransferMemberRecord findByOpenIdAndRecordNo(String openId, String recordNo) {
		return transferMemberRecordRepository.findByOpenIdAndRecordNo(openId, recordNo);
	}

	@Override
	public TransferMemberRecord executeBeiBiPay(TransferMemberRecord transferMemberRecord, Member member) {
		if (null == transferMemberRecord) {
			throw new ServiceException(StatusHouse.STATUS_ORDER_NOT_EXIST);
		}
		if (null == member) {
			throw new ServiceException(StatusHouse.STATUS_MEMBER_NOT_EXIST);
		}
		if (!transferMemberRecord.getOpenId().equals(member.getOpenId())
				&& !transferMemberRecord.getCardNo().equals(member.getCardNo())) {
			logger.error("订单【" + transferMemberRecord.getRecordNo() + "】所属用户与付款用户不一致");
			throw new ServiceException("error", "订单状态异常");
		}
		if (TransferMemberRecord.STATUS_NOT_PAY != transferMemberRecord.getStatus()) {
			logger.error("订单【" + transferMemberRecord.getRecordNo() + "】不是未支付状态");
			throw new ServiceException("error", "订单状态异常");
		}
		TransferMemberProduct transferMemberProduct = (TransferMemberProduct) transferMemberProductRepository
				.getById(transferMemberRecord.getTransferMemberProductId());

		// 扣减买方账户
		JinBiAccount jinBiAccount = jinBiAccountRepository
				.findJinBiAccountByCardNoAndOpenId(transferMemberRecord.getCardNo(), transferMemberRecord.getOpenId());
		if (!MD5Utils.verify(jinBiAccount.getBalance().doubleValue() * 10000 + "", jinBiAccount.getEncryption())) {
			logger.error("用户【" + member.getCardNo() + "】贝币账户金额异常!");
			throw new ServiceException("error", "贝币账户异常!");
		}
		if (jinBiAccount.getBalance().subtract(transferMemberRecord.getPayAmount()).doubleValue() < 0.0000999) {
			throw new ServiceException("error", "贝币账户余额不足!");
		}
		JinBiAccountTrace jinBiAccountTrace = new JinBiAccountTrace();
		jinBiAccountTrace.setJinBiAccountId(jinBiAccount.getId());
		jinBiAccountTrace
				.setChangeType(me.firstapp.module.weixin.jinbi.JinBiAccountTrace.ChangeType.TRANSFER_MEMBER_SUB);
		jinBiAccountTrace.setBeforeValue(jinBiAccount.getBalance());
		jinBiAccountTrace.setChangeValue(transferMemberRecord.getPayAmount());
		BigDecimal afterValue = BigDecimal.ZERO;
		afterValue = jinBiAccount.getBalance().subtract(transferMemberRecord.getPayAmount()).setScale(4,
				RoundingMode.HALF_UP);
		jinBiAccountTrace.setAfterValue(afterValue);
		jinBiAccountTrace.setChangeDate(Integer.valueOf(DateUtils.getDateStr(new Date(), "yyyyMMdd")));
		jinBiAccountTrace.setChangeTime(new Date());
		jinBiAccountTraceRepository.save(jinBiAccountTrace);

		jinBiAccount.setBalance(afterValue);
		jinBiAccount.setEncryption(MD5Utils.generate(afterValue.doubleValue() * 10000 + ""));
		jinBiAccount.setUpdateTime(new Date());
		jinBiAccountRepository.update(jinBiAccount);

		// 新增卖方账户
		JinBiAccount ownJinBiAccount = jinBiAccountRepository.findJinBiAccountByCardNoAndOpenId(
				transferMemberProduct.getOwnCardNo(), transferMemberProduct.getOwnOpenId());
		if (!MD5Utils.verify(ownJinBiAccount.getBalance().doubleValue() * 10000 + "",
				ownJinBiAccount.getEncryption())) {
			logger.error("用户【" + transferMemberProduct.getOwnCardNo() + "】贝币账户金额异常!");
			throw new ServiceException("error", "贝币账户异常!");
		}
		JinBiAccountTrace ownJinBiAccountTrace = new JinBiAccountTrace();
		ownJinBiAccountTrace.setJinBiAccountId(ownJinBiAccount.getId());
		ownJinBiAccountTrace
				.setChangeType(me.firstapp.module.weixin.jinbi.JinBiAccountTrace.ChangeType.TRANSFER_MEMBER_ADD);
		ownJinBiAccountTrace.setBeforeValue(ownJinBiAccount.getBalance());
		ownJinBiAccountTrace.setChangeValue(transferMemberRecord.getPayAmount());
		BigDecimal ownAfterValue = BigDecimal.ZERO;
		ownAfterValue = ownJinBiAccount.getBalance().add(transferMemberRecord.getPayAmount()).setScale(4,
				RoundingMode.HALF_UP);
		ownJinBiAccountTrace.setAfterValue(ownAfterValue);
		ownJinBiAccountTrace.setChangeDate(Integer.valueOf(DateUtils.getDateStr(new Date(), "yyyyMMdd")));
		ownJinBiAccountTrace.setChangeTime(new Date());
		jinBiAccountTraceRepository.save(ownJinBiAccountTrace);

		ownJinBiAccount.setBalance(ownAfterValue);
		ownJinBiAccount.setEncryption(MD5Utils.generate(ownAfterValue.doubleValue() * 10000 + ""));
		ownJinBiAccount.setUpdateTime(new Date());
		jinBiAccountRepository.update(ownJinBiAccount);

		transferMemberRecord.setStatus(TransferMemberRecord.STATUS_PAYED);
		transferMemberRecord.setPayTime(new Date());

		// ------------------------------------------------------------------------------

		List<TransferMemberProductItem> transferMemberProductItems = transferMemberProductItemRepository
				.findByTransferMemberProductId(transferMemberRecord.getTransferMemberProductId());
		for (TransferMemberProductItem transferMemberProductItem : transferMemberProductItems) {
			Member transferMember = (Member) memberRepository.getById(transferMemberProductItem.getMemberId());
			transferMember.setChiefOpenId(member.getOpenId());
			transferMember.setChiefCardNo(member.getCardNo());
			memberRepository.update(transferMember);
		}
		transferMemberRecord.setStatus(TransferMemberRecord.STATUS_COMPLETE);
		transferMemberRecord.setCompleteTime(new Date());
		transferMemberRecordRepository.update(transferMemberRecord);

		return transferMemberRecord;
	}

	@Override
	public List<TransferMemberRecord> findByStatus(Integer status) {
		return transferMemberRecordRepository.findByStatus(status);
	}

	@Override
	public TransferMemberRecord executeUpdate(TransferMemberRecord transferMemberRecord) {
		transferMemberRecordRepository.update(transferMemberRecord);
		return transferMemberRecord;
	}

	@Override
	public TransferMemberRecord executeCancel(TransferMemberRecord transferMemberRecord) {
		if (null == transferMemberRecord) {
			return null;
		}
		if (TransferMemberRecord.STATUS_NOT_PAY != transferMemberRecord.getStatus()) {
			logger.error("转让记录[" + transferMemberRecord.getRecordNo() + "]未处于未支付状态");
			return transferMemberRecord;
		}
		TransferMemberProduct transferMemberProduct = (TransferMemberProduct) transferMemberProductRepository
				.getById(transferMemberRecord.getTransferMemberProductId());
		if (TransferMemberProduct.STATUS_SELLED == transferMemberProduct.getStatus()) {
			transferMemberProduct.setStatus(TransferMemberProduct.STATUS_ON);
			transferMemberProductRepository.update(transferMemberProduct);
		}
		transferMemberRecord.setStatus(TransferMemberRecord.STATUS_CANCEL);
		transferMemberRecord.setCancelTime(new Date());
		transferMemberRecordRepository.update(transferMemberRecord);
		return transferMemberRecord;
	}

	@Override
	public Page<TransferMemberRecord> findTransferMemberRecordPage(Integer pageNo, Integer pageSize,
			Map<String, Object> searchParams, String sortParam, String sortType, Date startTime, Date endTime) {
		return transferMemberRecordRepository.findTransferMemberRecordPage(pageNo, pageSize, searchParams, sortParam,
				sortType, startTime, endTime);
	}

}
